/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fb.vis.types;

import java.util.List;
import java.util.GregorianCalendar;
import com.restfb.Facebook;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import static com.restfb.util.StringUtils.isBlank;
import static com.restfb.util.DateUtils.toDateFromShortFormat;

    /*
     * informace o uzivateli z fql dotazu - kv;li spravnemu namapovani napriklad sex -> gender    
     */    
    public class Friend {
        
      @Facebook
      private String uid;

      @Facebook
      private String name;
      
      @Facebook("sex")
      private String gender;
      
      @Facebook("birthday_date")
      private String birthday;
      
      private float xPosition;
      private float yPosition;
      
      /**
       * sirka zobrazeni pritele v grafu
       */
      public static final int WIDTH = 70;
      /**
       * vyska zobrazeni pritele v grafu
       */
      public static final int HEIGHT = 100;
      

        public String getGender() {
            return gender; 
        }

        public void setGender(String gender) {
            this.gender = gender;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getUid() {
            return uid;
        }

        public void setUid(String uid) {
            this.uid = uid;
        }

        public String getBirthday() {
            return birthday;
        }

        public void setBirthday(String birthday) {
            this.birthday = birthday;
        }

    public float getxPosition() {
        return xPosition;
    }

    public void setxPosition(float xPosition) {
        this.xPosition = xPosition;
    }

    public float getyPosition() {
        return yPosition;
    }

    public void setyPosition(float yPosition) {
        this.yPosition = yPosition;
    }
        
        

      public Date getBirthdayAsDate() {
        if (isBlank(getBirthday()) || getBirthday().split("/").length < 2)
          return null;

        return toDateFromShortFormat(birthday);
      }
      
      /**
       * @return age of user, -1 if birthday is not specified
       */
      public int getAge() {
          Date dateOfBirth = getBirthdayAsDate();
          if (dateOfBirth == null)
              return -1;
          Calendar cal1 = new GregorianCalendar();
          Calendar cal2 = new GregorianCalendar();
          int factor = 0; 
          cal1.setTime(dateOfBirth);
          cal2.setTime(new Date(System.currentTimeMillis()));
          if(cal2.get(Calendar.DAY_OF_YEAR) < cal1.get(Calendar.DAY_OF_YEAR)) {
                factor = -1; 
          }
          return cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR) + factor;
      }

     
 // aby bylo videt pres jstl
    public static int getHEIGHT() {
        return HEIGHT;
    }
 // aby bylo videt pres jstl
    public static int getWIDTH() {
        return WIDTH;
    }
    
    
      /**
       * @return age of user, -1 if birthday is not specified
       */
    public static int setFriendsPositions(List<Friend> friends, int graphWidth, int graphHeight) {
        // kontrola, jestli se pratele na graf vejdou, kdyz ne, tak zvetsim graf na max delku
        final float REZERVA = 2; // nasobek
        if (friends.size()*(WIDTH*HEIGHT)*REZERVA > graphWidth*graphHeight)
            graphHeight = 15000;
        
        Random rand = new Random();
        boolean correctPosition;
        for (Friend friend : friends) {
            correctPosition = false;
            while (!correctPosition){
                friend.setxPosition(rand.nextInt(graphWidth-WIDTH));
                friend.setyPosition(rand.nextInt(graphHeight-HEIGHT));
                correctPosition = true;
                for (Friend placedFriend : friends) {
                    if (placedFriend.equals(friend))
                        break;
                    if (isOverlap(friend, placedFriend)){
                        correctPosition = false;
                        continue;
                    }
                }
            }
        }
        return graphHeight;
    }
    
    private static boolean isOverlap(Friend friend1, Friend friend2) {
          boolean result = false;
        
          float[] c1x = new float[4]; 
          float[] c1y = new float[4]; 
          float[] c2x = new float[4]; 
          float[] c2y = new float[4]; 
          c1x[0] = friend1.getxPosition(); 
          c1y[0] = friend1.getyPosition();
          c1x[1] = friend1.getxPosition(); 
          c1y[1] = friend1.getyPosition() + HEIGHT;
          c1x[2] = friend1.getxPosition() + WIDTH; 
          c1y[2] = friend1.getyPosition() + HEIGHT;
          c1x[3] = friend1.getxPosition() + WIDTH; 
          c1y[3] = friend1.getyPosition(); 

          c2x[0] = friend2.getxPosition(); 
          c2y[0] = friend2.getyPosition();
          c2x[1] = friend2.getxPosition(); 
          c2y[1] = friend2.getyPosition() + HEIGHT;
          c2x[2] = friend2.getxPosition() + WIDTH; 
          c2y[2] = friend2.getyPosition() + HEIGHT;
          c2x[3] = friend2.getxPosition() + WIDTH; 
          c2y[3] = friend2.getyPosition();
          for(int c1s = 0; c1s < 4 && !result; c1s++){
            for(int c2s = 0; c2s < 4 && !result; c2s++){
               result = result || isLinesOverlap(c1x[c1s], c1y[c1s], c1x[(c1s+1)%4], c1y[(c1s+1)%4], c2x[c2s], c2y[c2s], c2x[(c2s+1)%4], c2y[(c2s+1)%4]);
            }
          }
        
        return result;
    }
    
    private static boolean isLinesOverlap(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4){
      float x = ((y2-y1)*(x4-x3)*x1 + (x2-x1)*(x4-x3)*(y3-y1) - (y4-y3)*(x2-x1)*x3) /  ((y2-y1)*(x4-x3) - (x2-x1)*(y4-y3));
      float y = (x*(y2-y1)+y1*(x2-x1)-x1*(y2-y1)) / (x2-x1);
      return (x>=Math.min(x1,x2) && x <= Math.max(x1,x2) && x>=Math.min(x3,x4) && x <= Math.max(x3,x4) && y>=Math.min(y1,y2) && y <= Math.max(y1,y2) && y>=Math.min(y3,y4) && y <= Math.max(y3,y4));
    }
  
      
      
    }
